Problem
【UR #5】怎样跑得更快
时间限制:
空间限制:
大力水手问禅师:“大师,我觉得我光有力气是不够的。比如我吃菠菜可以让力气更大,但是却没有提升跑步的速度。请问怎样才能跑得更快?我试过吃白菜,没有效果。”
禅师浅笑,答:“方法很简单,不过若想我教你,你先看看这道的题。”
令 (,一个质数)。
给你整数 。现在有整数 和 满足 ,且对于 满足:
其中 表示 和 除以 的余数相等。 表示 和 的最大公约数, 表示 和 的最小公倍数。
有 个询问,每次给出 ,请你解出 的值。
输入格式
第一行四个整数 。保证 。
接下来 行,每行 个整数依次表示 。保证 。
输出格式
共 行,每行对给出的 ,输出对应的 。
如果有多组解输出任意一组即可。
如果无解那么这一行只用输出一个整数 。
样例输入输出
样例一
Input
1 | 3 1 0 2 |
Output
1 | 499122179 998244352 499122176 |
Explanation
对于第一个询问,要满足的等式为:
样例二
见样例数据下载。
限制与约定
对于所有数据,,。
测试点编号 | 其他 | ||
---|---|---|---|
保证有唯一解 | |||
保证有唯一解 | |||
保证有唯一解 | |||
保证有唯一解 | |||
无 |
后记
还没听完题,大力水手就嘶吼着:“太难了我不会我不会!”,飞快地跑掉了。
禅师看着大力水手消失的背影,叹了口气说:“你们这些人啊,每天就想做些大水题,一碰到难题,跑得不知道比谁都快。”
后来大力水手把的题题面贴在了汽车的后挡风玻璃上,人类从此掌握了光速旅行的正确方式。
下载
标签:莫比乌斯反演
Solution
先膜一发vfk的题解。
首先将题目中的式子转换一下:
设,那么原式化为
此时可以强行”说一句废话“来加入反演。存在数论函数使得,那么,这样若知道,即可枚举约数求出,即
1 | for (int i = 1; i <= n; i++) fr[i] = f[i]; |
将带入原式即可得到
令,,那么
我们知道右边,要求左边,于是再次做反演,即,即
1 | for (int i = 1; i <= n; i++) fz[i] = b[i]*Pow(g(i), P-2); |
这样就得到了的值,即得到的值,于是即可算出的值。
然后再尝试用推出。由于,设,那么。
仍然是反演的形式,再次反演得到,即
1 | for (int i = 1; i <= n; i++) hx[i] = z[d]; |
知道了,即可由求出的值。
总结一下,分为三次反演:
- 预处理的值(线性筛),反演求
- 读入,反演求,乘的逆元即可得到
- 通过反演求,乘的逆元即可得到
Code
1 |
|